﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;

namespace Jet.Dal.Exceptions
{
	[Serializable]
	[ComVisible(true)]
	[ClassInterface(ClassInterfaceType.None)]
	public class ValidationException : DataLayerException
	{
		private readonly Tuple<string, string>[] _errors = new Tuple<string, string>[0];

		/// <summary>
		/// Errors in format property name-error text
		/// </summary>
		public IList<Tuple<string, string>> Errors { get { return _errors; } }
		
		/// <summary>
		/// Initializes a new instance of the ValidationException class.
		/// </summary> 
		public ValidationException()
		{
			
		}

		/// <summary>
		/// Initializes a new instance of the ValidationException with validation errors list
		/// <exception cref="ArgumentNullException">when errors are null</exception>
		/// </summary>
		public ValidationException(IEnumerable<Tuple<string, string>> errors)
		{
			if (errors==null)
			{
				throw new ArgumentNullException("errors");
			}
			_errors = errors.ToArray();
		}

		/// <summary>
		/// Initializes a new instance of the ValidationException class with a specified error message.
		/// </summary>
		public ValidationException(string message)
			:base(message)
		{
			
		}

		/// <summary>
		/// Initializes a new instance of the ValidationException class with a specified error message and a reference to the inner exception that is the cause of this exception.
		/// </summary>
		public ValidationException(string message, Exception innerException)
			:base(message, innerException)
		{
			
		}

		/// <summary>
		/// Initializes a new instance of the ValidationException class with serialized data.
		/// </summary>
		protected ValidationException(SerializationInfo info, StreamingContext context)
			:base(info, context)
		{
			var count = info.GetInt32("Length");
			_errors = new Tuple<string, string>[count];
			for (var i = 0; i < _errors.Length; i++)
			{
				var property = info.GetString(String.Format("Property{0}", i));
				var value = info.GetString(String.Format("Value{0}", i));
				_errors[i] = new Tuple<string, string>(property, value);
			}
		}

		public override void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			info.AddValue("Length", _errors.Length);
			for(var i=0; i<_errors.Length; i++)
			{
				info.AddValue(String.Format("Property{0}",i), _errors[i].Item1);
				info.AddValue(String.Format("Value{0}",i), _errors[i].Item2);
			}
			base.GetObjectData(info, context);
		}
	}
}
